/*
 * @Author: Trae AI
 * @Date: 2024-07-15
 * @Description: 规划网格控制器
 */
import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Post,
  Put,
  Query,
  Res,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { RequiresPermissions } from 'src/common/decorators/requires-permissions.decorator';
import { PaginationPipe } from 'src/common/pipes/pagination.pipe';
import {
  AddSysGuideDto,
  GetSysGuideListDto,
  UpdateSysGuideDto,
  GetEnabledGuideListDto,
} from './dto/req-sys-guide.dto';
import { SysGuideService } from './sys-guide.service';
import { BusinessTypeEnum, Log } from 'src/common/decorators/log.decorator';
import { RepeatSubmit } from 'src/common/decorators/repeat-submit.decorator';
import { CreateMessagePipe } from 'src/common/pipes/createmessage.pipe';
import { DataObj } from 'src/common/class/data-obj.class';
import { UpdateMessagePipe } from 'src/common/pipes/updatemessage.pipe';
import { StringToArrPipe } from 'src/common/pipes/stringtoarr.pipe';
import { Public } from 'src/common/decorators/public.decorator';
import { FileInterceptor } from '@nestjs/platform-express';
import { ParseFilePipeBuilder } from '@nestjs/common';
import { Response } from 'express';
import { ExcelService } from 'src/modules/common/excel/excel.service';
import { ImportSysGuideDto, UpdateSupportDto } from './dto/import-sys-guide.dto';
import { Keep } from 'src/common/decorators/keep.decorator';
import { StreamableFile } from '@nestjs/common';
import { ApiException } from 'src/common/exceptions/api.exception';

@Controller('system/guide')
export class SysGuideController {
  constructor(
    private readonly sysGuideService: SysGuideService,
    private readonly excelService: ExcelService,
  ) { }

  /* 获取第一条指南数据 */
  @Get('first')
  @Public()
  async getFirst() {
    const guide = await this.sysGuideService.getFirstGuide();
    return DataObj.create(guide);
  }

  /* 获取启用的指南列表（小程序端使用） */
  @Get('enabled')
  @Public()
  async enabledList(@Query(PaginationPipe) getEnabledGuideListDto: GetEnabledGuideListDto) {
    return await this.sysGuideService.enabledList(getEnabledGuideListDto);
  }

  /* 通过id获取指南详情 */
  @Get('enabled/:id')
  @Public()
  async getGuideById(@Param('id') id: number) {
    const guide = await this.sysGuideService.oneByGuideId(id);
    return DataObj.create(guide);
  }

  /* 新增 */
  @Post()
  @RepeatSubmit()
  @Log({
    title: '规划网格管理',
    businessType: BusinessTypeEnum.insert,
    isSaveRequestData: false,
  })
  @RequiresPermissions('system:guide:add')
  async add(@Body(CreateMessagePipe) addSysGuideDto: AddSysGuideDto) {
    await this.sysGuideService.add(addSysGuideDto);
  }

  /* 分页查询 */
  @Get('list')
  @RequiresPermissions('system:guide:query')
  async list(@Query(PaginationPipe) getSysGuideListDto: GetSysGuideListDto) {
    return await this.sysGuideService.list(getSysGuideListDto);
  }

  /* 通过id查询 */
  @Get(':guideId')
  @RequiresPermissions('system:guide:query')
  async oneByGuideId(@Param('guideId') guideId: number) {
    const guide = await this.sysGuideService.oneByGuideId(guideId);
    return DataObj.create(guide);
  }

  /* 更新 */
  @Put()
  @RepeatSubmit()
  @RequiresPermissions('system:guide:edit')
  @Log({
    title: '规划网格管理',
    businessType: BusinessTypeEnum.update,
    isSaveRequestData: false,
  })
  async update(
    @Body(UpdateMessagePipe) updateSysGuideDto: UpdateSysGuideDto,
  ) {
    await this.sysGuideService.update(updateSysGuideDto);
  }

  /* 删除 */
  @Delete(':guideIds')
  @RequiresPermissions('system:guide:remove')
  @Log({
    title: '规划网格管理',
    businessType: BusinessTypeEnum.delete,
  })
  async delete(
    @Param('guideIds', new StringToArrPipe()) guideIdArr: number[],
  ) {
    await this.sysGuideService.delete(guideIdArr);
  }

  /* 下载模板 */
  @RepeatSubmit()
  @Post('importTemplate')
  @Keep()
  async importTemplate(@Res() res: Response) {
    const file = await this.excelService.importTemplate(ImportSysGuideDto, '规划网格导入模板');
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodeURIComponent('规划网格导入模板.xlsx')}`);
    const buffer = file instanceof StreamableFile ? file.getStream() : file;
    res.send(buffer);
  }

  /* 导入数据 */
  @Post('importData')
  @RepeatSubmit()
  @RequiresPermissions('system:guide:import')
  @UseInterceptors(FileInterceptor('file'))
  async importData(
    @Query() updateSupportDto: UpdateSupportDto,
    @UploadedFile(
      new ParseFilePipeBuilder()
        .addMaxSizeValidator({
          maxSize: 1024 * 1024 * 5,
        })
        .addFileTypeValidator({
          fileType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        })
        .build({
          exceptionFactory: (error) => {
            throw new ApiException('文件格式错误！ 文件最大为5M，且必须是 xlsx 格式');
          },
        }),
    )
    file: Express.Multer.File,
  ) {
    const data = await this.excelService.import<ImportSysGuideDto>(
      ImportSysGuideDto,
      file,
    );
    const result = await this.sysGuideService.importData(data, updateSupportDto.updateSupport);
    return {
      msg: `导入成功。成功数量：${result.successCount}，失败数量：${result.failCount}`,
      data: result
    };
  }
}